﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace CSharpTaskWaitAndContinue
{
    internal class Program
    {
        static void Main(string[] args)
        {
            //Test1();
            //Test2();
            Test3();

            Console.ReadLine();
        }

        static void Test1()
        {
            Thread thread1 = new Thread(() =>
            {
                Thread.Sleep(2000);
                Console.WriteLine("子线程1.....\r\n");
            });

            Thread thread2 = new Thread(() =>
            {
                Thread.Sleep(1000);
                Console.WriteLine("子线程2.....\r\n");
            });

            thread1.Start();
            thread2.Start();

            thread1.Join(); //让调用线程阻塞
            thread2.Join();

            Console.WriteLine("这个是主线程....");
        }

        static void Test2()
        {
            Task task1 = new Task(() =>
            {
                Thread.Sleep(2000);
                Console.WriteLine($"Task1子线程Id={Thread.CurrentThread.ManagedThreadId} {DateTime.Now.ToLongTimeString()}");
            });
            task1.Start();

            Task task2 = new Task(() =>
            {
                Thread.Sleep(1000);
                Console.WriteLine($"Task2子线程Id={Thread.CurrentThread.ManagedThreadId} {DateTime.Now.ToLongTimeString()}");
            });
            task2.Start();

            //第一种方式 :依次等待，和前面一样
            /*task1.Wait();
            task2.Wait();*/

            //第二种方式：等待所有任务完成【推荐】
            Task.WaitAll(task1,task2);

            //第三种方式: 等待任何一个线程完成即可【推荐】
            Task.WaitAny(task1,task2);


            Console.WriteLine("主线程开始运行！Time=" +DateTime.Now.ToLongTimeString());
        }

        static void Test3()
        {
            Task task1 = new Task(() =>
            {
                Thread.Sleep(2000);
                Console.WriteLine($"Task1子线程Id={Thread.CurrentThread.ManagedThreadId} {DateTime.Now.ToLongTimeString()}");
            });
            task1.Start();

            Task task2 = new Task(() =>
            {
                Thread.Sleep(1000);
                Console.WriteLine($"Task2子线程Id={Thread.CurrentThread.ManagedThreadId} {DateTime.Now.ToLongTimeString()}");
            });
            task2.Start();

            /*//第三个子线程，希望在前面两个子线程都执行完毕后再去执行
            Task.WhenAll(task1, task2).ContinueWith(task =>
            {
                // 在这里可以编写你需要的业务...
                Console.WriteLine($"Task3子线程Id={Thread.CurrentThread.ManagedThreadId} {DateTime.Now.ToLongTimeString()}");
            });*/

            //第三个子线程，希望在前面“任意”两个子线程中的一个完成，就执行
            Task.WhenAny(task1, task2).ContinueWith(task =>
            {
                // 在这里可以编写你需要的业务...
                Console.WriteLine($"Task3子线程Id={Thread.CurrentThread.ManagedThreadId} {DateTime.Now.ToLongTimeString()}");
            });

            Console.WriteLine("主线程开始运行！Time=" + DateTime.Now.ToLongTimeString());
        }
    }
}
